"use strict";
console.log('ts');
// let arr1 = [40, 50, 60, 80, 90, 100]
// let arr2 = arr1.map(i => {
//     return i >= 60 ? "及格" : "不及格"
// })
// console.log(arr2)
var str = "您好ts";
console.log(str);
/*
vsCode配置自动编译
1.弟一步： tsc生成 tsconfig.json  改js输出路劲 "outDir": "./js",
2.第二步： 点击菜单-终端-运行任务-typescript-tsc:监视tsconfig.json
*/
/*
数据类型

布尔类型：boolean
数字类型：number
字符串类型：string
数组类型：array
元组类型：tuple
枚举类型：enam
任意类型：any
null和undefined类型
void类型
never类型

*/
/*
typescript中为了使编写的代码更规范，更有利于维护，增加了类型校验
写ts代码必须指定类型
*/
//布尔类型：Boolean
// var flag: boolean = true;
// flag=123 //错误写法
// flag = false
// console.log(flag)
//数字类型：number
// var num: number = 123
// num=4
//数组类型：array
//1.第一种定义数组的方式
var arr1 = [11, 22, 33];
console.log(arr1);
//2.第二种定义数组的方式
var arr2 = [1, 22, 33];
console.log(arr2);
//3.第三种定义数组的方式
var arr3 = ['123232', 22, true];
console.log(arr3);
//元组类型：tuple 属于数组的一种
// var arr: Array<number> = [11, 22, 33]
// console.log(arr)
//可以给数组里得每个元素指定类型
// let arrtuple: [number, string] = [123, 'this is ts']
// console.log(arrtuple)
/*
枚举类型:enum
enum 枚举名{
    标识符[=整型常数],
    ...
    标识符[=整型常数]
}
*/
// enum Flag { success = 1, error = 2 };
// let s: Flag = Flag.success
// console.log(s)
// enum Color { blue, red = 3, 'orange' }
// var c: Color = Color.red
// console.log(c) //3
// var c: Color = Color.orange
// console.log(c)
// enum Err { 'undefined' = -1, 'null' = -2, 'success' = 1 }
// var e: Err = Err.success
// console.log(e)
//任意类型：any
// var num: any = 3
// num = 'str'
// num=true
// console.log(num)
//任意类型的用处
// var oBox: any = document.getElementById('box')
// oBox.style.color='red'
//null和undefined 其他 (never类型) 数据类型的子类型
// var num: number;
// console.log(num) //输出：undefined  //正确
// var num: number | undefined;
// num = 123
// console.log(num)
//定义没有复制就是undefined
// var num: number | undefined
// console.log(num)
// var mum: null;
// num = null
//一个元素可能是number类型 可能是null 可能是undefined
// var num: number | null| undefined;
// num = 123;
// console.log(num)
//void类型：typescript中的void表示没有任何类型，一般用于定义方法的时候方法没有返回值
//表示方法没有饭会任何类型
/*function ren(): void{
    console.log('ren')
}
ren()
*/
//错误写法
// function run(): undefined{
//     console.log('run')
// }
// run()
//正确写法
// function run(): number{
//     return 123;
// }
// run()
//never类型：是其他类型 (包括null和undefined) 的子类型，代表从不会出现的值
//着意味着声明never的变量只能被never类型所赋值
// var a: undefined;
// a = undefined;
// var b: null;
// b = null;
// console.log(a,b)
// var a: never;
// a = 123; //错误的写法
// a = (() => {
//     throw new Error('错误')
// })()
//3.1 ts中定义函数
// function age(): number{
//     return 12
// }
// var fun1 = function (): string{
//     return '1223232'
// }
//3.2 ts中定义方法传参
// function getInfo(name: string, age: number): string{
//     return `${name}---${age}`
// }
// getInfo('zhangsan', 23)
//3.3 没遇返回值的方法
function run() {
    console.log('run');
}
run();
//3.4 方法可选参数  参数后面加个 ? 表示可传可不传
// function getInfo(name: string, age?: number): string{
//     if (age) {
//         return `${name}---${age}`
//     } else {
//         return `${name}---年龄保密`
//     }
// }
// alert(getInfo('zhangsan', 20))
// alert(getInfo('zhangsan'))
//主意可选参数必须配置在最后面
//3.5 默认参数
// function getInfo(name: string, age: number=20): string{
//     if (age) {
//         return `${name}---${age}`
//     } else {
//         return `${name}---年龄保密`
//     }
// }
// alert(getInfo('zhangsan',30))
//3.6 剩余参数
// function sum(a: number, b: number, c: number, d: number): number{
//     return a+b+c+d
// }
// alert(sum(1, 2, 3, 4))
//三点运算符 接受新参数过来的值
// function sum(a:number,b:number,...result:number[]): number{
//     return a +b + result.reduce((i, j) => {
//         return i + j
//     })
// }
// alert(sum(1, 2, 3, 4))
// 3.7. ts函数重载
// function getInfo(name: string): string;
// function getInfo(age: number): number;
// function getInfo(str: any): any{
//     if (typeof str === 'string') {
//         return '我叫：'+ str
//     } else {
//         return '我的年龄是:'+ str
//     }
// }
// alert(getInfo('张三'))
// alert(getInfo(20))
//1.ts中定义类
// class Person{
//     name: string; //属性 前面省略了public关键词
//     constructor(n:string) { //构造函数  实例化类的时候出发的方法
//         this.name = n;
//     }
//     run(): void{
//         alert(this.name)
//     }
// }
// var p = new Person('张三')
// p.run()
// class Person{
//     name: string; //属性 前面省略了public关键词
//     constructor(name:string) { //构造函数  实例化类的时候出发的方法
//         this.name = name;
//     }
//     getName(): string{
//         return this.name
//     }
//     setName(name: string): void{
//         this.name = name
//     }
// }
// var p = new Person('张三')
// alert(p.getName())
// p.setName('李四')
// alert(p.getName())
//2.ts中如何实现继承 extends super
// class Person{
//     name: string; //属性 前面省略了public关键词
//     constructor(name:string) { //构造函数  实例化类的时候出发的方法
//         this.name = name;
//     }
//     run(): string{
//         return `${this.name}在运动`
//     }
// }
// var p = new Person('张三')
// alert(p.run())
// class Web extends Person{
//     constructor(name: string) {
//         super(name);    //初始化弗雷的构造函数
//     }
// }
// var w = new Web('李四')
// w.run()
//2.ts中继承的探讨  父类的方法和子类的方法一致
// class Person{
//     name: string; //属性 前面省略了public关键词
//     constructor(name:string) { //构造函数  实例化类的时候出发的方法
//         this.name = name;
//     }
//     run(): string{
//         return `${this.name}在运动`
//     }
// }
// // var p = new Person('张三')
// // alert(p.run())
// class Web extends Person{
//     constructor(name: string) {
//         super(name);    //初始化弗雷的构造函数
//     }
//     work() {
//         alert(`${this.name}在工作`)
//     }
// }
// var w = new Web('李四')
// w.work()
//3.类里面的修饰符 typescript里面定义属性的时候给我们提供了三种修饰符
/*
    public: 公有    在类里面、子类、类外面都可以访问
    protected: 保护类型   在类里面、子类里面都可以访问，在类外部没法访问
    private:   私有     在类里面可以访问，子类、类外都没法访问

    属性如果不加修饰符 默认就是公有
*/
//public: 公有    在类里面、子类、类外面都可以访问
// class Person{
//     public name: string; //   公有属性
//     constructor(name:string) { //构造函数  实例化类的时候出发的方法
//         this.name = name;
//     }
//     run(): string{
//         return `${this.name}在运动`
//     }
// }
// // var p = new Person('张三')
// // alert(p.run())
// class Web extends Person{
//     constructor(name: string) {
//         super(name);    //初始化弗雷的构造函数
//     }
//     run(): string{
//         return `${this.name}在运动`
//     }
//     work() {
//         alert(`${this.name}在工作`)
//     }
// }
// var w = new Web('李四')
// w.work()
//类外部访问公有属性
// class Person{
//     public name: string; //   公有属性
//     constructor(name:string) { //构造函数  实例化类的时候出发的方法
//         this.name = name;
//     }
//     run(): string{
//         return `${this.name}在运动`
//     }
// }
// var p = new Person('哈哈哈')
// alert(p.name)
//protected: 保护类型   在类里面、子类里面都可以访问，在类外部没法访问
// class Person{
//     protected name: string; //   保护属性
//     constructor(name:string) { //构造函数  实例化类的时候出发的方法
//         this.name = name;
//     }
//     run(): string{
//         return `${this.name}在运动`
//     }
// }
// // var p = new Person('张三')
// // alert(p.run())
// class Web extends Person{
//     constructor(name: string) {
//         super(name);    //初始化弗雷的构造函数
//     }
//     run(): string{
//         return `${this.name}在运动`
//     }
//     work() {
//         alert(`${this.name}在工作`)
//     }
// }
// var w = new Web('李四111')
// // w.work()
// alert(w.run())
//类外部没法访问保护类型的属性
// class Person{
//     protected name: string; //   保护属性
//     constructor(name:string) { //构造函数  实例化类的时候出发的方法
//         this.name = name;
//     }
//     run(): string{
//         return `${this.name}在运动`
//     }
// }
// var p = new Person('张三')
// alert(p.name)
//private:   私有     在类里面可以访问，子类、类外都没法访问
// class Person{
//     private name: string; //   保护属性
//     constructor(name:string) { //构造函数  实例化类的时候出发的方法
//         this.name = name;
//     }
//     run(): string{
//         return `${this.name}在运动`
//     }
// }
// class Web extends Person{
//     constructor(name: string) {
//         super(name)
//     }
//     work(): string{
//         return `${this.name}在工作`
//     }
// }
// class Person{
//     private name: string; //   保护属性
//     constructor(name:string) { //构造函数  实例化类的时候出发的方法
//         this.name = name;
//     }
//     run(): string{
//         return `${this.name}在运动`
//     }
// }
// var p = new Person('啊哈哈哈')
// alert(p.run())
//静态属性  静态方法
/*
    es5里的静态方法

    function Person() {
        this.run1 = function () {  //实例方法
            
        }
    }
    Person.run2 = function () { //静态方法
        
    }
    var p = new Person();
    Person.run2()   //静态方法的调用

*/
//ts里定义静态方法
// class Person{
//     public name: string
//     public age: number = 20
//     static sex: string = '男'
//     constructor(name: string) {
//         this.name = name
//     }
//     run() {
//         alert(`${this.name}在运动`)
//     }
//     work() {
//         alert(`${this.name}在工作`)
//     }
//     static print() {  //静态方法 里面没法直接调用类里面的属性
//         alert('print方法' + this.sex)
//     }
// }   
// // var p = new Person('张三')  //调用实例方法
// // p.run()
// Person.print()  //调用静态方法
// alert(Person.sex)
//多态：父类定义一个方法不去实现，让继承他的子类去实现  每一个子类有不同的表现
//多态属于继承
// class Animal{
//     name: string;
//     constructor(name:string) {
//         this.name = name
//     }
//     eat() { //具体吃什么  由继承他的子类去实现每一个子类的表现不一样
//         console.log('吃的方法')
//     }
// }
// class Dog extends Animal{
//     constructor(name: string) {
//         super(name)
//     }
//     eat() {
//         return `${this.name}吃肉`
//     }
// }
// class Cat extends Animal{
//     constructor(name: string) {
//         super(name)
//     }
//     eat() {
//         return `${this.name}吃鱼`
//     }
// }
//typescript中的抽象类： 它是提供其他类继承的基类，不能直接被实例化
//用abstract关键字定义抽象类和抽象方法，抽象类中的抽象方法不包含具体实现并且必须在派生类中实现
//abstract抽象方法只能放在抽象类里面
//抽象类和抽象方法用来定义标准， 标准：Animal 这个类要求它的子类必须包含eat方法
//标准：
// abstract class Animal {
//     public name: string;
//     constructor(name: string) {
//         this.name = name
//     }
//     abstract eat(): any;    //抽象类中的抽象方法不包含具体实现并且必须在派生类中实现
//     run() {
//         console.log('其他方法可以不实现')
//     }
// }
// // var a = new Animal()    //错误的写法
// class Dog extends Animal {
//     //抽象类的子类必须实现抽象类里面的抽象方法
//     constructor(name:any) {
//         super(name)
//     }
//     eat() {
//         console.log(this.name+'吃粮食')
//     }
// }
// var d = new Dog('点点')
// d.eat()
// class Cat extends Animal {
//     constructor(name:any) {
//         super(name)
//     }
//     run() {
//     }
//     eat() {
//         console.log(this.name+'吃小鱼')
//     }
// }
// var c = new Cat('小花')
// c.eat()
